using Microsoft.EntityFrameworkCore;
using KnowledgeQA.Models.Entities;

namespace KnowledgeQA.Data
{
    /// <summary>
    /// 知识库问答系统数据库上下文
    /// </summary>
    public class KnowledgeQADbContext : DbContext
    {
        public KnowledgeQADbContext(DbContextOptions<KnowledgeQADbContext> options) : base(options)
        {
        }

        /// <summary>
        /// 文档表
        /// </summary>
        public DbSet<Document> Documents { get; set; } = null!;

        /// <summary>
        /// 分类表
        /// </summary>
        public DbSet<Category> Categories { get; set; } = null!;

        /// <summary>
        /// 文档块表
        /// </summary>
        public DbSet<DocumentChunk> DocumentChunks { get; set; } = null!;

        /// <summary>
        /// 聊天会话表
        /// </summary>
        public DbSet<ChatSession> ChatSessions { get; set; } = null!;

        /// <summary>
        /// 聊天消息表
        /// </summary>
        public DbSet<ChatMessage> ChatMessages { get; set; } = null!;

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            // 配置实体关系
            ConfigureRelationships(modelBuilder);

            // 配置索引
            ConfigureIndexes(modelBuilder);

            // 配置种子数据
            ConfigureSeedData(modelBuilder);
        }

        /// <summary>
        /// 配置实体关系
        /// </summary>
        /// <param name="modelBuilder">模型构建器</param>
        private void ConfigureRelationships(ModelBuilder modelBuilder)
        {
            // Document 和 Category 关系
            modelBuilder.Entity<Document>()
                .HasOne(d => d.Category)
                .WithMany(c => c.Documents)
                .HasForeignKey(d => d.CategoryId)
                .OnDelete(DeleteBehavior.SetNull);

            // Document 和 DocumentChunk 关系
            modelBuilder.Entity<DocumentChunk>()
                .HasOne(dc => dc.Document)
                .WithMany(d => d.DocumentChunks)
                .HasForeignKey(dc => dc.DocumentId)
                .OnDelete(DeleteBehavior.Cascade);

            // Category 自引用关系（父子分类）
            modelBuilder.Entity<Category>()
                .HasOne(c => c.Parent)
                .WithMany(c => c.Children)
                .HasForeignKey(c => c.ParentId)
                .OnDelete(DeleteBehavior.Restrict);

            // ChatSession 和 ChatMessage 关系
            modelBuilder.Entity<ChatMessage>()
                .HasOne(cm => cm.Session)
                .WithMany(cs => cs.Messages)
                .HasForeignKey(cm => cm.SessionId)
                .OnDelete(DeleteBehavior.Cascade);

            // ChatMessage 自引用关系（回复关系）
            modelBuilder.Entity<ChatMessage>()
                .HasOne(cm => cm.ParentMessage)
                .WithMany(cm => cm.Replies)
                .HasForeignKey(cm => cm.ParentMessageId)
                .OnDelete(DeleteBehavior.Restrict);
        }

        /// <summary>
        /// 配置索引
        /// </summary>
        /// <param name="modelBuilder">模型构建器</param>
        private void ConfigureIndexes(ModelBuilder modelBuilder)
        {
            // Document 索引
            modelBuilder.Entity<Document>()
                .HasIndex(d => d.Title)
                .HasDatabaseName("IX_Documents_Title");

            modelBuilder.Entity<Document>()
                .HasIndex(d => d.FileType)
                .HasDatabaseName("IX_Documents_FileType");

            modelBuilder.Entity<Document>()
                .HasIndex(d => d.Status)
                .HasDatabaseName("IX_Documents_Status");

            modelBuilder.Entity<Document>()
                .HasIndex(d => d.CreatedAt)
                .HasDatabaseName("IX_Documents_CreatedAt");

            // Category 索引
            modelBuilder.Entity<Category>()
                .HasIndex(c => c.Name)
                .HasDatabaseName("IX_Categories_Name");

            modelBuilder.Entity<Category>()
                .HasIndex(c => c.ParentId)
                .HasDatabaseName("IX_Categories_ParentId");

            // DocumentChunk 索引
            modelBuilder.Entity<DocumentChunk>()
                .HasIndex(dc => dc.DocumentId)
                .HasDatabaseName("IX_DocumentChunks_DocumentId");

            modelBuilder.Entity<DocumentChunk>()
                .HasIndex(dc => dc.VectorId)
                .HasDatabaseName("IX_DocumentChunks_VectorId");

            modelBuilder.Entity<DocumentChunk>()
                .HasIndex(dc => dc.IsVectorized)
                .HasDatabaseName("IX_DocumentChunks_IsVectorized");

            // ChatSession 索引
            modelBuilder.Entity<ChatSession>()
                .HasIndex(cs => cs.UserId)
                .HasDatabaseName("IX_ChatSessions_UserId");

            modelBuilder.Entity<ChatSession>()
                .HasIndex(cs => cs.Status)
                .HasDatabaseName("IX_ChatSessions_Status");

            modelBuilder.Entity<ChatSession>()
                .HasIndex(cs => cs.LastActiveAt)
                .HasDatabaseName("IX_ChatSessions_LastActiveAt");

            // ChatMessage 索引
            modelBuilder.Entity<ChatMessage>()
                .HasIndex(cm => cm.SessionId)
                .HasDatabaseName("IX_ChatMessages_SessionId");

            modelBuilder.Entity<ChatMessage>()
                .HasIndex(cm => cm.MessageType)
                .HasDatabaseName("IX_ChatMessages_MessageType");

            modelBuilder.Entity<ChatMessage>()
                .HasIndex(cm => cm.CreatedAt)
                .HasDatabaseName("IX_ChatMessages_CreatedAt");
        }

        /// <summary>
        /// 配置种子数据
        /// </summary>
        /// <param name="modelBuilder">模型构建器</param>
        private void ConfigureSeedData(ModelBuilder modelBuilder)
        {
            // 添加默认分类
            modelBuilder.Entity<Category>().HasData(
                new Category
                {
                    Id = 1,
                    Name = "默认分类",
                    Description = "系统默认分类",
                    SortOrder = 0,
                    IsEnabled = true,
                    CreatedAt = DateTime.Now,
                    UpdatedAt = DateTime.Now
                },
                new Category
                {
                    Id = 2,
                    Name = "技术文档",
                    Description = "技术相关文档",
                    SortOrder = 1,
                    IsEnabled = true,
                    CreatedAt = DateTime.Now,
                    UpdatedAt = DateTime.Now
                },
                new Category
                {
                    Id = 3,
                    Name = "产品文档",
                    Description = "产品相关文档",
                    SortOrder = 2,
                    IsEnabled = true,
                    CreatedAt = DateTime.Now,
                    UpdatedAt = DateTime.Now
                }
            );
        }

        /// <summary>
        /// 重写保存更改方法，自动设置更新时间
        /// </summary>
        /// <returns>影响的行数</returns>
        public override int SaveChanges()
        {
            UpdateTimestamps();
            return base.SaveChanges();
        }

        /// <summary>
        /// 重写保存更改方法（异步），自动设置更新时间
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>影响的行数</returns>
        public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            UpdateTimestamps();
            return base.SaveChangesAsync(cancellationToken);
        }

        /// <summary>
        /// 更新时间戳
        /// </summary>
        private void UpdateTimestamps()
        {
            var entries = ChangeTracker.Entries<BaseEntity>()
                .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);

            foreach (var entry in entries)
            {
                if (entry.State == EntityState.Added)
                {
                    entry.Entity.CreatedAt = DateTime.Now;
                }
                entry.Entity.UpdatedAt = DateTime.Now;
            }
        }
    }
} 